#!/usr/bin/env python
# encoding: utf-8
"""
tableclient.py

Created by 黄 冬 on 2007-12-19.
Copyright (c) 2007 __MyCompanyName__. All rights reserved.
"""

from twisted.internet import reactor,defer
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.protocols.basic import Int16StringReceiver
import logging.config

log = logging.getLogger('xbaytable.tools.tableclient')
#logging.basicConfig(level=logging.ERROR)
#logging.basicConfig(level=logging.WARNING)
#logging.basicConfig(level=logging.DEBUG)

from xbaytable.conf import *
from xbaytable.utils.tablemsg import *

class TableClientProtocol(Int16StringReceiver):
    """实现table protocol"""
    def stringReceived(self, msg):
        """有数据需要接收了"""
        command,sequence_id=self.process.recv_head(msg[0:4])
        log.debug('client recv command %s,sequence %s'%(command['command_name'],sequence_id))
        log.debug('command msg is %s'%repr(msg[4:]))
        self.sendwin.remove(sequence_id)
        if (command['command_id'] == 2):
            #如果没有bind认证通过，还不是一个bind的请求，哪么关闭这个新来的连接
            self.bind = True
            d = defer.maybeDeferred(self.AuthOK)
        elif(self.bind):
            d = self.process_command(command,sequence_id,msg)
            #self.transport.loseConnection()

    def process_command(self,command,sequence_id,msg):
        """处理发来的请求"""
        d = defer.Deferred()
        eval('self.process.process_%s(self,command,sequence_id,msg[4:])'%command['command_name'])
        return d

    def connectionMade(self):
        """建立了连接后先发出table_bind请求进行认证"""
        #发送出去的报文窗口记录
        self.sendwin = []
        #是不是与服务器建立完成了bind认证
        self.bind=False
        #处理消息的对象进行初始化
        self.process =self.factory.process()
        #向服务器发出bind请求
        sequence_id = self.process.send_bind_table(self,TABLE_USERNAME,TABLE_PASSWORD)
        self.sendwin.append(sequence_id)

    def AuthOK(self):
        """
        Override this.
        """
        raise NotImplementedError

class TableClientFactory(ClientFactory):
    """客户端连接工厂类"""
    def __init__(self, protocol, process):
        self.process = process
        self.protocol = protocol
        
    def clientConnectionFailed(self,connect,reason):
        """连接失败"""
        log.error('Connect to server failed.Reason:%s'%reason)
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        log.info('Connect Server Lost.')
        reactor.stop()